import PySimpleGUI as sg
from pptx import Presentation
import os,datetime,copy,six,openpyxl
from pptx.util import Inches, Pt ,Emu


class Window(sg.Window):
    def __init__(self):
        super().__init__('PPT转换工具')
        self._path = getDesktopPath()
        self.show()

    def show(self):
        sg.theme('GreenMono')
        self.layout = [
            [sg.Text('选择需汇总PPT的目录',size=(18,1)),sg.Input(key='folder',size=(40,1)),sg.FolderBrowse()],
            [sg.Ok()],
            [sg.Text('选择需转换的PPT',size=(18,1)),sg.Input(key='filename',size=(40,1)),sg.FileBrowse()],
            [sg.Text('选择目标文件夹',size=(18,1)),sg.Input(key='local',default_text=self._path,size=(40,1)),sg.FolderBrowse()],

            [sg.Submit(), sg.Cancel()]
        ]
        self.root = sg.Window('PPT转换工具', self.layout)


def getDesktopPath():
    return os.path.join(os.path.expanduser("~"),'Desktop')


def replace(tar_file, org_file):
    #格式：目标ppt的表格坐标：源ppt的表格坐标
    replace_list1 = {(0, 1): (0, 1),
                    (1, 4): (1, 2),
                    (6, 2): (0, 2)}
    #由于源ppt的表格是分开2个shape的，所以要2个列表
    replace_list2 = {(4, 0): (2, 0),
                     (4, 4): (2, 1),
                     (5, 2): (2, 1)}
    org_pr = Presentation(org_file)
    tar_pr = Presentation(tar_file)
    index = 0
    for slide in org_pr.slides:
        shape_list = []
        for shape in slide.shapes:
            if shape.has_table:
                shape_list.append(shape)
        for key, value in replace_list1.items():
            text1 = shape_list[0].table.cell(value[0], value[1]).text.split('：')[-1].strip()
            #print(text1)
            tar_pr.slides[index].shapes[1].table.cell(key[0], key[1]).text += text1
        for key, value in replace_list2.items():
            text2 = shape_list[1].table.cell(value[0], value[1]).text.split('：')[-1].strip()
            #print(text2)
            tar_pr.slides[index].shapes[1].table.cell(key[0], key[1]).text += text2
        tar_pr.slides[index].shapes[1].table.cell(1, 7).text = str(datetime.datetime.today().month) + '月份'
        tar_pr.slides[index].shapes[1].table.cell(6, 5).text = '提升设备可靠性'
        for cell in tar_pr.slides[index].shapes[1].table.iter_cells():
            for paragraph in cell.text_frame.paragraphs:
                for run in paragraph.runs:
                    run.font.size = Pt(12)
        index = index + 1
        print('第%s页内容已转换' % index)
        tar_pr.save('test.pptx')
    return 'test.pptx'

def getimage(tar_file, org_file):
    '''
    :param tar_file: 将图片插入的目标文件
    :param org_file: 从源文件哪里找到图片并插入目标文件
    :return: 返回保存的文件名字
    '''
    org_pr = Presentation(org_file)
    tar_pr = Presentation(tar_file)
    index = 0
    #从第1页第2个shape开始（根据ppt组织形态定的）
    shape = tar_pr.slides[0].shapes[1]
    if shape.has_table:
        #获得放置图片的table左侧的位置
        tab_left = 10 * int(shape.table.cell(3, 0).margin_left)
        #获得放置图片的table表框宽度
        width = shape.width
        #获得放置图片的table右侧的位置
        tab_right = tab_width = int(width / 2)
        #print(tab_right)
    for slide in org_pr.slides:
        #图片放置的顶部位置
        top = Inches(1.65)
        for shape in slide.shapes:
            #如果shape里面是存在图片的
            if '图片' in shape.name or 'Picture' in shape.name:
                #picture = shape._pic
                #获得每个图片并保存在硬盘
                image = shape.image
                with open('picture.jpg', 'wb') as f:
                    f.write(image.blob)
                #图片放置的高度
                height = Inches(2.1)
                #设置一个temp（中间对象），获得图片放进去后的尺寸，在参与后面的计算（将图片放置到框的中间）
                temp = Presentation()
                title_slide_layout = temp.slide_layouts[0]
                slide = temp.slides.add_slide(title_slide_layout)
                p = slide.shapes.add_picture('picture.jpg', 0, 0, height=height)
                pic_width = p.width
                #插入图片
                if is_1st_img(shape):
                    #print('这是第一张照片')
                    x = tab_left + (tab_width/2 - pic_width/2)
                    #print('照片的坐标是%s' % x )
                else:
                    #print('\n这是第二张照片~~~~')
                    x = tab_left + tab_width + (tab_width/2 - pic_width/2)
                    #print('照片的坐标是%s' % x)
                #插入图片
                pic = tar_pr.slides[index].shapes.add_picture('picture.jpg', x, top, height=height)
        index += 1
        print('第%s页内容已转换' % index)
    tar_pr.save('改善-提交总部格式.pptx')
    return '改善-提交总部格式.pptx'


def image_position(shape):
    '''
    pptx本身就是一个zip文件，将其扩展名改为.zip后，打开压缩包，在ppt/slides/子目录内，每一页（slide）对应一个xml文件。
    使用Chrome浏览器打开xml文件，按F12可以看到xml的结构，是一个一个tag的，跟html的文件一样的。
    <p:pic>
        <p:nvPicPr>
            <p:cNvPr id="2" name="图片 1" descr="微信图片_20200214152651"/>
            <p:cNvPicPr>
                <a:picLocks noChangeAspect="1"/>
            </p:cNvPicPr>
            <p:nvPr/>
        </p:nvPicPr>
        <p:blipFill>
            <a:blip r:embed="rId3"/>
            <a:stretch>
                <a:fillRect/>
            </a:stretch>
        </p:blipFill>
        <p:spPr>
            <a:xfrm>
                <a:off x="5981700" y="2288540"/>
                <a:ext cx="5664835" cy="2512060"/>
            </a:xfrm>
            <a:prstGeom prst="rect">
                <a:avLst/>
            </a:prstGeom>
        </p:spPr>
    </p:pic>
    :param shape:一个shape，带图片的shape一般名字都含“图片”或“Picuture”
    :return: 返回图片的位置坐标x,y(左上角位置，起始坐标）,cx,cy(右下角位置坐标)
    '''
    '''
    "._pic"对应<p:pic>的tag
    使用xpath方法查找shape._element（即以上段落），里面的子段落<p:spPr>，的孙子段落<a:xfrm>，取得<a:off>的属性"x"的参数
    以下同理
    若查找图片的id，则是shape._element.blipFill.blip.get('r:embed')
    '''
    picture = shape._pic
    x = shape._element.spPr.xfrm.off.get('x')
    y = shape._element.spPr.xfrm.off.get('y')
    cx = shape._element.spPr.xfrm.ext.get('cx')
    cy = shape._element.spPr.xfrm.ext.get('cy')
    return int(x), int(y), int(cx), int(cy)


def is_1st_img(shape, threshold=3000000):
    '''
    :param shape: 包含图片的shape
    :param threshold:阈值，判断哪个位置左侧是第一个图片
    :return:
    '''
    x, y, _, _ = image_position(shape)
    if x < threshold:
        return True
    else:
        return False


def delete_slides(presentation, index):
    '''
    本方法用于删除一个pptx对象内特定的一页
    :param presentation: 一个pptx对象，打算对哪一个文件进行操作
    :param index: 删除那一页
    :return: None
    '''
    #获得所有页的xml格式
    xml_slides = presentation.slides._sldIdLst
    #转换成列表
    slides = list(xml_slides)
    #删除列表某个索引的值
    xml_slides.remove(slides[index])


def remove_silde(file,path):
    '''
    本方法用于删除一个pptx对象内空白的一页
    :param file: 需要操作哪个文件
    :return: 直接保存
    '''
    pr = Presentation(file)
    #获得PPT有多少页（索引需要减去1）
    index = len(pr.slides)-1
    while True:
        #倒叙删除
        if index > len(pr.slides)-1:
            continue
        #从最后一页开始查询，(5, 2)格空白的删除
        for shape in pr.slides[index].shapes:
            if shape.has_table:
                if shape.table.cell(5, 2).text == "":
                    delete_slides(pr, index)
                    print('删除第%s页ppt' % str(index+1))
        index = index - 1
        if index == 0:
            break
    pr.save(os.path.join(path,('三工厂改善提报%s.pptx' % datetime.datetime.today().strftime('%Y-%m-%d'))))


def copy(tar_file, org_file, index=0):
    #格式：目标ppt的表格坐标：源ppt的表格坐标
    copy_list1 = {(0, 1): (0, 1), (0, 2): (0, 2), (1, 2): (1, 2)}
    copy_list2 ={(2, 0): (2, 0), (2, 1): (2, 1)}
    i = 0
    #生成源文件PPT和目标文件PPT的对象
    org_pr = Presentation(org_file)
    print(org_file)
    tar_pr = Presentation(tar_file)
    #以目标文件PPT第1页第3个shape为对象（包含了table）
    shape = tar_pr.slides[0].shapes[2]
    #获得填充招标的表框离侧面的距离，以及表框的宽度
    if shape.has_table:
        tab_left = 10 * int(shape.table.cell(2, 0).margin_left)
        width = shape.width
    for slide in org_pr.slides:
        shape_list = []
        #开始复制PPT的文字，找到有table的shape
        for shape in slide.shapes:
            if shape.has_table:
                shape_list.append(shape)
        #根据对照的dict，一个一个表格内容复制
        try:
            for key, value in copy_list1.items():
                text1 = shape_list[0].table.cell(value[0], value[1]).text.split('：')[-1].strip()
                tar_pr.slides[index].shapes[1].table.cell(key[0], key[1]).text += text1
            for key, value in copy_list2.items():
                text2 = shape_list[1].table.cell(value[0], value[1]).text.split('：')[-1].strip()
                tar_pr.slides[index].shapes[2].table.cell(key[0], key[1]).text += text2
        except Exception as e:
            print(e)
            file = r'C:\Users\hyq\Desktop\ok.pptx'
            if not os.path.exists(file):
                tar_pr.save(file)
            return index, org_file
        #开始复制照片，找到有照片的shape
        for shape in slide.shapes:
            #获得源文件PPT的图片并保存
            if '图片' in shape.name or 'Picture' in shape.name:
                image = shape.image
                with open('picture.jpg', 'wb') as f:
                    f.write(image.blob)
                x, y, cx,cy = image_position(shape)
                top = Inches(2.5)
                height = Inches(2.8)
                if is_1st_img(shape):
                    x = tab_left
                else:
                    x = tab_left + width/2
                tar_pr.slides[index].shapes.add_picture('picture.jpg', x, top, height=height)
                #print('cy=%s' % cy)
        index = index + 1
        i +=1
    #tar_pr.save('ok.pptx')
    return index,tar_pr

#得出PPT里面有几个改善，空白的不算
def getPPT(slides):
    number = 0
    for slide in slides:
        for shape in slide.shapes:
            if shape.has_table:
                try:
                    if shape.table.cell(0, 1).text:
                        #打印改善名字，改善实施人
                        #print(shape.table.cell(0, 1).text, shape.table.cell(0, 2).text )
                        number = number + 1
                        continue
                except:
                    pass
    return number

def get_all_number(org_path):
    for path in os.listdir(org_path):
        current_path = os.path.join(org_path, path)
        if os.path.isdir(current_path):
            for file in os.listdir(current_path):
                if os.path.splitext(file)[-1] == '.ppt':
                    ppt2pptx(file)
                elif os.path.splitext(file)[-1] == '.pptx':
                    try:
                        prs = Presentation(os.path.join(current_path, file))
                        slides = prs.slides
                        much[path] = much[path] + getPPT(slides)
                    except Exception as e:
                        print(e)
                        print('%s文件格式错误' % path)
    return much


if __name__ == '__main__':
    much = {}
    name_list = {
        '李争华': 'lizhenghua@hisense.com',
        '胡高祥': 'hugaoxiang@hisense.com',
        '郑源富': 'zhengyuanfu@hisense.com',
        '周景耀': 'zhoujingyao@hisense.com',
        '王青': 'wangqing9@hisense.com',
        '罗仕新': 'luoshixin@hisense.com',
        '黄冠辉': 'huangguanhui@hisense.com',
        '霍佳胜': 'huojiasheng@hisense.com',
        '何伟忠': 'heweizhong@hisense.com',
        '莫海林': 'mohailin@hisense.com',
        '韩国彪': 'hanguobiao@hisense.com',
        '伍志森': 'wuzhisen@hisense.com',
        '郑秋利': 'zhengqiuli@hisense.com',
    }
    for key in name_list.keys():
        much[key] = 0
    tar_file = '目标格式.pptx'
    window = Window()
    while True:
        event, values = window.root.read()
        print(event,values)
        if event == 'Submit':
            try:
                org_file = values['filename']
                path = values['local']
                temp1 = replace(tar_file,org_file)
                temp2 = getimage(temp1, org_file)
                remove_silde(temp2, path)
                os.remove(temp1)
                os.remove(temp2)
                os.remove('picture.jpg')
                sg.popup( '已完成PPT格式转换~~')
            except Exception as e:
                print(e)
                sg.popup('未选择正确的PPT文件！！！')
        elif event is None or event == 'Cancel':
            break
        elif event == 'Ok':
            tar_file = r'C:\Users\hyq\Desktop\改善格式.pptx'
            org_path = values['folder']
            dic = get_all_number(org_path)
            #将改善数量存入excel
            wb = openpyxl.Workbook()
            sheet = wb.active
            sheet.append(["名字", "提报改善数量"])
            sheet.column_dimensions['A'].width = 8
            sheet.column_dimensions['B'].width = 14
            for name, value in much.items():
                sheet.append([name, value/2])
            wb.save(os.path.join(values['local'],'改善数量汇总.xlsx'))
            #开始转换pptx
            index = 0
            for path in os.listdir(org_path):
                current_path = os.path.join(org_path, path)
                if os.path.isdir(current_path):
                    for file in os.listdir(current_path):
                        if os.path.splitext(file)[-1] == '.ppt':
                            sg.popup('暂时不支持ppt格式')
                        elif os.path.splitext(file)[-1] == '.pptx':
                            index,tar_pr = copy(tar_file,os.path.join(current_path, file),index)
                            tar_file = r'C:\Users\hyq\Desktop\ok.pptx'
                            try:
                                tar_pr.save(tar_file)
                                print('copy success %s ！' % os.path.join(current_path, file))
                            except Exception as e:
                                print('%s文件存在问题！！' % tar_pr)
            sg.popup('已完成改善汇总~~')
    window.close()